﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuickGraph;
using QuickGraph.Serialization;
using QuickGraphBuilder;
using GraphInformation;
using System.IO;
using EdgeWithAttributes;
namespace EpidemicSimulator
{
    public class SimulationFactory
    {
        public static TEdge CreateEdge<TVertex, TEdge>(TVertex source, TVertex target, string desc)
            where TVertex : DiseaseModelNode, new()
            where TEdge : DiseaseModelEdge
        {
            TEdge edge = (TEdge)new DiseaseModelEdge(source, target);
            return edge;
        }

        public static Simulation createSimulation(SimulationSetup setup, String pathToSaveDLL)
        {
            var diseaseModelGraph = new AdjacencyGraph<DiseaseModelNode, DiseaseModelEdge>();

            if (setup.diseaseModelGraphML != null)
            {
                StringReader reader = new StringReader(setup.diseaseModelGraphML);
                try
                {

                    diseaseModelGraph.DeserializeFromGraphML(
                        reader,
                        id => new DiseaseModelNode(),
                        new IdentifiableEdgeFactory<DiseaseModelNode, DiseaseModelEdge>(CreateEdge<DiseaseModelNode, DiseaseModelEdge>)
                        );
                }
                catch (Exception e)
                {
                    throw e;
                }

                reader.Close();
            }

            UndirectedGraph<SocialNetworkNode, EdgeWithAttributes<SocialNetworkNode>> network = null;
            if (setup.networkGraph != null)
            {
                network = setup.networkGraph.GetGraphFormSilverlight();
            }
            else
            {
                network = GraphMLBuilder.Build<SocialNetworkNode>(setup.networkGraphML, pathToSaveDLL);
            }

            //!!!
            foreach(var edge in network.Edges) 
            {
                edge.Condition = setup.condition;
            }

            Simulation simulation = new Simulation(diseaseModelGraph, network);
            simulation.setMaxContactsPerStep(setup.maxContactsPerStep);
            simulation.setMinContactsPerStep(setup.minContactsPerStep);
            simulation.reset();
            simulation.stopConditions = setup.stopConditions;
            //simulation.makeStateChanges(setup.stateChangePlans);
            foreach (var plan in setup.stateChangePlans)
            {
                simulation.addStateChangePlan(plan);
            }

            return simulation;
        }
    }
}
